home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Collection of Tools & Utilities
/
Collection of Tools and Utilities.iso
/
tex
/
filtr21.zip
/
FILTER21.C
< prev
next >
Wrap
C/C++ Source or Header
|
1994-06-08
|
9KB
|
328 lines
/* `filter', v. 2.1 Latest mod: 12:30 Jun 8 1994
A `grep'-like text searcher for multiple simultaneous keyword tests
Copyright 1994 by Joel Polowin, Department of Chemistry, Queen's University,
Kingston, Ontario, Canada. Permission granted for free use and distribution;
I want credit/blame for writing it. E-mail: polowin@silicon.chem.queensu.ca,
polowinj@qucdn.queensu.ca, Joel.Polowin@p4.f107.n249.z1.fidonet.org .
If you see something wrong with it or it fails to work, PLEASE let me know!
*/
#define LENGTH 601 /* 1 more than max # characters */
#define ARGS 2000
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
void syntax ()
{
fprintf(stderr,"Syntax: filter [filename] [filename ...] string [string ...]\n where");
fprintf(stderr," each string (max. of %d) is a term to be searched for",ARGS);
fprintf(stderr," in lines (max.\n %d chars) in file",LENGTH-1);
fprintf(stderr," `filename', prefixed by one of the following characters:\n");
fprintf(stderr," + to show lines which contain string\n");
fprintf(stderr," - to show lines which do not contain string\n");
fprintf(stderr," = to show lines which contain string, case sensitive\n");
fprintf(stderr," _ (underscore) to show lines which do not contain string,\n");
fprintf(stderr," case sensitive\n\n");
fprintf(stderr,"A string as above may be further prefixed with the letter 'o' to\n");
fprintf(stderr," print the line if the current OR the preceding condition is true.");
fprintf(stderr,"\nA string including blanks and the prefix may be enclosed in");
fprintf(stderr," double quotes.\nStrings beginning with one of `$&^' designate");
fprintf(stderr," file expansion; see filter21.doc.\n\nExamples:\n filter armorial");
fprintf(stderr," =Vert +argent -gules _Or -azure -purpur +foil > tempfile.txt\n");
fprintf(stderr," type temp1.txt | filter +aardvark \042o+winged pig\042 ");
fprintf(stderr,"o+wombat \042_|B|\042\n\nFilter utility v.2.1 (C) 1994 by Joel");
fprintf(stderr," Polowin, Chem. Dept., Queen's University,\nKingston. Permission");
fprintf(stderr," granted for free use; I want credit/blame for writing it.\n");
fprintf(stderr,"polowin@silicon.chem.queensu.ca, polowinj@qucdn.queensu.ca\n");
exit(1);
}
void main(argc,argv)
int argc;
char *argv[];
{
char line[LENGTH],lowline[LENGTH];
FILE *infile;
int i,j,k,l,test,firststring,nostring,lowcase;
void syntax();
void strlow();
char flag[ARGS+1],orflag[ARGS+1];
char *myargv[ARGS+1];
int blocksize;
char *prefix,*filename;
firststring=0;
for(i=1; i<argc; i++)
{
if(*argv[i]=='=' || *argv[i]=='+' || *argv[i]=='-' || *argv[i]=='_')
{
test=*argv[i];
for(j=1; test==*(argv[i]+j); j++)
;
if(j%2 && firststring==0)
firststring=i;
argv[i]+=j/2;
}
}
if(firststring==0)
{
fprintf(stderr,"Must specify a search string.\n");
syntax();
}
nostring=argc-firststring;
if(nostring>ARGS)
{
fprintf(stderr,"Too many search strings specified.\n");
syntax();
}
lowcase=0;
for (i=0; i<ARGS+1; i++) orflag[i]=0;
blocksize=0;
for (i=firststring; i<argc; i++) blocksize+=strlen(argv[i])+1;
if (NULL==(myargv[1]=malloc(blocksize)))
{
fprintf(stderr,"Can't allocate memory for string storage.\n");
exit(1);
}
strcpy(myargv[1],argv[firststring]);
for(i=2; i<=nostring; i++)
{
myargv[i]=myargv[i-1]+strlen(myargv[i-1])+1;
strcpy(myargv[i],argv[i+firststring-1]);
}
for (i=1; i<=nostring; i++)
{
j=0;
switch(*myargv[i])
{
case '+':
strlow(myargv[i]);
lowcase=1;
case '=':
flag[i]=1;
break;
case '-':
strlow(myargv[i]);
lowcase=1;
case '_':
flag[i]=0;
break;
case 'O':
case 'o':
orflag[i-1]=1;
myargv[i]++;
i--;
j=1;
break;
default:
fprintf(stderr,"Error in string no. %d: %s\n",i-1,myargv[i]);
syntax();
}
if((!j) && (((test=*(myargv[i]+1))=='$') || (test=='&') || (test=='^')))
{
for(j=1; test==*(myargv[i]+1+j); j++)
; /* count identical flag chars */
l=j/2;
for (k=0; *(myargv[i]+k)!='\0'; k++) /* shift string to delete */
*(myargv[i]+k+1)=*(myargv[i]+k+l+1); /* half of flag chars */
if(j%2) /* an odd number of flag chars: expand file */
{
if(test=='^')
{
prefix="";
orflag[i-1]=0;
}
else
{
switch(*myargv[i]) /* determine prefix for expanded terms */
{ /* from current prefix and expansion type */
case '+':
if(test=='$') prefix="o+";
else prefix="+";
break;
case '=':
if(test=='$') prefix="o=";
else prefix="=";
break;
case '-':
if(test=='$') prefix="-";
else prefix="o-";
break;
case '_':
if(test=='$') prefix="_";
else prefix="o_";
break;
default:
fprintf(stderr,"Bugger-up in program!\n");
exit(1);
}
}
filename=myargv[i]+2;
if(!(infile=fopen(filename,"r")))
{
fprintf(stderr,"Can't open search-term file %s\n",filename);
exit(1);
}
if(test!='^') test=*myargv[i]; /* prefix of current term */
blocksize=0; /* figure out how much memory to allocate */
for(j=0;;j++) /* for new terms */
{
if(NULL==fgets(line,LENGTH,infile)) break;
if(LENGTH==strlen(line)+1) fprintf(stderr,
"* Warning: truncated search term file %s line\n%s\n",
filename,line);
if(line[strlen(line)-1]=='\n') line[strlen(line)-1]='\0';
blocksize+=strlen(line)+1;
}
if (j==0)
{
fprintf(stderr,"* Warning: empty search term file %s\n",
filename);
j=1;
}
blocksize+=j*strlen(prefix);
rewind(infile);
if(nostring+j-1>ARGS)
{
fprintf(stderr,"File expansion gives too many terms (%d max)\n",
ARGS);
exit(1);
}
for(k=nostring; k>i; k--) /* shift old myargv to make room */
myargv[k+j-1]=myargv[k];
if(NULL==(myargv[i]=malloc(blocksize)))
{
fprintf(stderr,"Can't allocate memory for search term expansion.\n");
exit(1);
}
for(k=0;k<j;k++)
{
fgets(line,LENGTH,infile);
if(line[strlen(line)-1]=='\n') line[strlen(line)-1]='\0';
if(k==0)
{
if(test=='^') strcpy(myargv[i],line);
else
{
*myargv[i]=test;
strcpy(myargv[i]+1,line);
}
}
else
{
myargv[i+k]=myargv[i+k-1]+strlen(myargv[i+k-1])+1;
strcpy(myargv[i+k],prefix);
strcat(myargv[i+k],line);
}
}
fclose(infile);
nostring+=j-1;
i--;
}
}
}
k=0;
do
{
k++;
if(firststring==1) infile=stdin;
else
if(!(infile=fopen(argv[k],"r")))
{
fprintf(stderr,"Can't open file %s for reading.\n",argv[k]);
syntax();
}
l=0;
for (;;)
{
if(NULL==fgets(line,LENGTH,infile)) break;
if(LENGTH==strlen(line)+1) fprintf(stderr,"* Warning: truncated line \n%s\n",line);
if(lowcase) strlow(strcpy(lowline,line));
for(i=1; i<=nostring; i++)
{
test=0;
switch(*myargv[i])
{
case '=':
case '_':
if(NULL!=strstr(line,(myargv[i]+1))) test=1;
break;
default:
if(NULL!=strstr(lowline,(myargv[i]+1))) test=1;
break;
}
if(test!=flag[i] && orflag[i]==0) break;
if(test==flag[i])
while(orflag[i]==1) i++;
}
if(i>nostring)
{
if(firststring>2 && l==0)
{
printf("File %s:\n",argv[k]);
l=1;
}
printf("%s",line);
}
}
if(infile!=stdin) fclose(infile);
}
while(k<firststring-1);
exit(0);
}
void strlow(string)
char *string;
{
while (*string!='\0')
{
*string=tolower(*string);
string++;
}
}
/* Revision history:
Version 1.0 September 1992.
1.1